/**
 * Copyright (c) 2017-2018, zengjintao (1913188966@qq.com).
 * <p>
 * Licensed under the GNU Lesser General Public License (LGPL) ,Version 3.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.gnu.org/licenses/lgpl-3.0.txt
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.jfast.framework.web.orm;

import java.lang.reflect.Field;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.jfast.framework.bean.ClassFactory;
import com.jfast.framework.bean.JdkClassFactory;
import com.jfast.framework.exception.DataSourceException;
import com.jfast.framework.kit.StrKit;
import com.jfast.framework.orm.TypeConvert;
import com.jfast.framework.orm.annotation.Column;

public final class ModelBuilder {

	private static final ModelBuilder modelBuilder = new ModelBuilder();
	private final ClassFactory classFactory = new JdkClassFactory();

	public static ModelBuilder me(){
		return modelBuilder;
	}

	private ModelBuilder() {

	}

	public void fillStatement(PreparedStatement preparedStatement, Object[] params) throws SQLException {
		StringBuilder sb = new StringBuilder("parameters: ");
		if (params != null) {
			for (int i = 0; i < params.length; i++) {
				preparedStatement.setObject(i + 1, params[i]);
				sb.append(params[i] + "(" + TypeConvert.getClassTypeToString(params[i].getClass()) + ")" + ",");
			}
		}
		System.out.println(sb.toString());
	}

	public <T> List<T> builderModelList(ResultSet resultSet, Class<T> cla) throws Exception {
		List<T> result  = new ArrayList<T>();
		while (resultSet.next()) {
			T t = classFactory.createBean(cla);
			Field[] fields = cla.getDeclaredFields();
			for (Field field : fields) {
				field.setAccessible(true);
				Column column = field.getAnnotation(Column.class);
				if (StrKit.isNotEmpty(column) && StrKit.isNotEmpty(column.name())) {
					field.set(t, resultSet.getObject(column.name()));
				} else {
					field.set(t, resultSet.getObject(field.getName()));
				}
			}
			result.add(t);
		}
		return result;

	}

	public Map<String, Object> builderToMap(ResultSet resultSet) throws SQLException {
		Map<String, Object> map = new HashMap<>();
		ResultSetMetaData metaData = resultSet.getMetaData();
		int columnCount = metaData.getColumnCount();
		String[] columnNames = new String[columnCount];
		for (int i = 0; i < columnCount; i++) {
			String columnName = metaData.getColumnLabel(i + 1);
			columnNames[i] = columnName;
		}
		while (resultSet.next()) {
			for (String name : columnNames) {
				Object value =  resultSet.getObject(name);
				map.put(name, value);
			}
		}
		return map;
	}
}
